package com.lvmama.utils;

import com.lvmama.common.enums.CommonParentType;
import com.lvmama.pojo.dto.rhino.CommonStatisticsSqlVO;
import com.lvmama.pojo.dto.rhino.tree.DeviceStatisticsSqlVO;
import com.lvmama.pojo.dto.rhino.tree.NettypeStatisticsSqlVO;
import com.lvmama.pojo.dto.rhino.tree.RegionStatisticsSqlVO;
import com.lvmama.pojo.dto.rhino.tree.StatisticsSqlVO;
import com.lvmama.pojo.entity.rhino.CommonStatisticsResult;
import com.lvmama.pojo.entity.rhino.tree.CodeNode;
import com.lvmama.pojo.entity.rhino.tree.TreeNodeView;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class TreeNodeViewUtil {
	
	public static List<TreeNodeView> nodeList = new ArrayList<TreeNodeView>();
	public static List<CodeNode> codeList = new ArrayList<CodeNode>();
	public static Map<String,List> codeTypeMap = new HashMap<String,List>();
	public static List<CodeNode> pagePriorityList = new ArrayList();
	public static Map<String, Integer> levelStringMap = new HashMap<String, Integer>();
	
	public static final String Channel = "Channel";
	public static final String Device = "Device";
	public static final String Page = "Page";
	
	public static final String AttrSet_Separator = ",";
	
	public static int _3Shou = 1;
	public static int _3z = 2;
	public static int _3PinD = 2;
	public static int _3SouS = 2;
	public static int _3XagQ = 4;
	public static int _3XiaD = 5;
	public static int _3ZhiF = 6;
	public static int[] pageLevel = new int[]{_3Shou,_3z,_3PinD,_3SouS,_3XagQ,_3XiaD,_3ZhiF};
	
	public static Properties treeUtilProperties = new Properties();
	
	static{
		codeTypeMap.put("Root", Arrays.asList("Channel","Device","Page"));
		codeTypeMap.put("Channel", Arrays.asList("Channel","Device","Page"));
		codeTypeMap.put("Device", Arrays.asList("Device","Page"));
		codeTypeMap.put("Page", Arrays.asList("Page"));
		//设定页面的优先级
		//levelStringMap.put("3Shou", 1);
		//levelStringMap.put("3z", 2);
		//levelStringMap.put("3PinD", 2);
		//levelStringMap.put("3SouS", 2);
		//levelStringMap.put("3XagQ", 3);
		//levelStringMap.put("3XiaD", 4);
		//levelStringMap.put("3ZhiF", 5);
		
		//treeUtilProperties = getProperties("treeutil.properties");
		treeUtilProperties.put("category.15", "跟团游");
		treeUtilProperties.put("category.16", "当地游");
		treeUtilProperties.put("category.17", "酒店套餐");
		treeUtilProperties.put("category.1", "度假酒店");
		treeUtilProperties.put("category.5", "门票");
		treeUtilProperties.put("column.page_code","Page");
		treeUtilProperties.put("column.channel_code","Channel");
		treeUtilProperties.put("column.platform_code","Device");
		treeUtilProperties.put("column.category_id","category");
		treeUtilProperties.put("CM","移动");
		treeUtilProperties.put("CU","联通");
		treeUtilProperties.put("CT","电信");
		treeUtilProperties.put("NONE","其他");
	}
	
	//暂时不用pros文件，每次都提交不上
	public static final Properties getProperties(String path) {
		Properties properties = new Properties();
		try {
			properties.load(new InputStreamReader(TreeNodeViewUtil.class.getClassLoader().getResourceAsStream(path),"UTF-8"));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return properties;
	}
	
	/**
	 * 
	* @Title: checkAttributeSet 
	* @Description: 校验节点属性值，返回布尔值
	 */
	public static boolean checkAttributeSet(String attSet,String attValue){
		//可以判断节点的多个属性是否合法
		if("category".equals(attSet)){
			CommonParentType[] commonParentType = CommonParentType.getVSTProduct();
			for(CommonParentType c : commonParentType){
				if(c.getValue().equals(attValue)){
					return true;
				}
			}
		}
		return false;
	}
	
	public static List<String> getCodeTypeList(String ct){
		return (List<String>) codeTypeMap.get(ct);
	}
	
	/**
	 * 
	* @Title: getPageLevelChildrenByLevel 
	* @Description: 根据页面的优先级得到子节点，例如详情页》订单页》订单完成页
	* @return void    返回类型 
	* @throws
	 */
	public static List<CodeNode> getPageLevelChildrenByLevel(String pageCode){
		List<CodeNode> list = new ArrayList();
		int pagePriority = levelStringMap.get(pageCode);
		for(String str : levelStringMap.keySet()){
			if(pagePriority < levelStringMap.get(str)){
				CodeNode cn = TreeNodeViewUtil.getCodeNodeByCode(str, codeList);
				list.add(cn);
			}
		}
		return list;
	}
	
	/**
	 * 
	* @Title: formatValue 
	* @Description: 格式化指定的格式
	* @param @return    设定文件 
	* @return List<Map<String,String>>    返回类型 
	* @throws
	 */
	public static List<Map<String,String>> formatValue(List<Map<String,CodeNode>> list){
		List<Map<String,String>> lists = new ArrayList();
		
		for (Map<String, CodeNode> m : list){
			for (String k : m.keySet()){
				CodeNode cn = m.get(k);
				String str = cn.getName();
				CodeNode parentCn = getParentCodeNode(cn);
				str = (parentCn == null?"":parentCn.getName()) + "-" + str;
				Map map = new HashMap();
				map.put(k, str);
				lists.add(map);
			}
	    }  
		return lists;
	}
	
	/**
	 * 
	* @Title: getParentCodeNode 
	* @Description: 获取父节点 
	* @param @param cn
	* @param @return    设定文件 
	* @return CodeNode    返回类型 
	* @throws
	 */
	public static CodeNode getParentCodeNode(CodeNode cn){
		for(CodeNode codeNode : codeList){
			if(codeNode.getId().equals(cn.getParentId())){
				return codeNode;
			}
		}
		return null;
	}
	
	/**
	 * 
	* @Title: getAllChildrenCodeNodeByCodeType 
	* @Description: 获取codeType类型下的所有code码值
	* @param @param codeType
	* @param @param cnList
	* @param @return    设定文件 
	* @return List    返回类型 
	* @throws
	 */
	public static List<CodeNode> getAllChildrenCodeNodeByCodeType(String codeType,List<CodeNode> cnList){
		List<CodeNode> list = new ArrayList<CodeNode>();
		for(CodeNode codeNode : cnList){
			if(codeNode.getCodetype().equals(codeType)){
				list.add(codeNode);
			}
		}
		return list;
	}
	
	/**
	 * 
	* @Title: getAllChildrenCodeNode 
	* @Description: 遍历code码表，得到此节点下的所有子节点，包括子节点的节点
	* @param @param cn
	* @param @param cnList
	* @param @return    设定文件 
	* @return List    返回类型 
	* @throws
	 */
	public static List<CodeNode> getAllChildrenCodeNode(CodeNode cn,List<CodeNode> cnList){
		List<CodeNode> list = new ArrayList<CodeNode>();
		for(CodeNode codeNode : cnList){
			if(codeNode.getParentId() != null && codeNode.getParentId().equals(cn.getId())){
				List<CodeNode> listChildren = getAllChildrenCodeNode(codeNode,cnList);
				list.add(codeNode);
				list.addAll(listChildren);
			}
		}
		return list;
	}
	/**
	 * 
	* @Title: refreshNodeList 
	* @Description: 重新赋值树列表
	* @return void    返回类型 
	* @throws
	 */
	public static void refreshNodeList(List<TreeNodeView> list){
		nodeList.clear();
		//判断nodelist树节点的属性信息，过滤掉非法的值
		for(TreeNodeView tnv : list){
			boolean Flag = true;
			String attributeSetStr = tnv.getAttributeSet();
			if(attributeSetStr != null && attributeSetStr.length()>0){
				String[] attList = attributeSetStr.split(TreeNodeViewUtil.AttrSet_Separator);
				String[] attValueList = tnv.getAttributeValues().split(TreeNodeViewUtil.AttrSet_Separator);
				for(int i = 0;i < attList.length ; i++){
					if("category".equals(attList[i])){
						if(TreeNodeViewUtil.checkAttributeSet("category", attValueList[i])){
							
						}else{
							Flag = false;
						}
					}
				}
			}
			if(Flag){
				nodeList.add(tnv);
			}
		}
		//nodeList.addAll(list);
	}
	
	/**
	 * 
	* @Title: refreshNodeList 
	* @Description: 重新赋值code码表
	* @return void    返回类型 
	* @throws
	 */
	public static void refreshCodeList(List<CodeNode> list){
		//初始化设备字段的映射
		for(CodeNode cn : list){
			//if(cn.getName().startsWith("ios")||cn.getName().startsWith("android")){
				treeUtilProperties.put(cn.getCode(), cn.getName());
			//}
		}
		codeList.clear();
		codeList.addAll(list);
	}
	
	/**
	 * 
	* @Title: getTreeNodeViewById 
	* @Description: 根据ID得到此树节点信息
	* @param @param id
	* @param @param list
	* @return TreeNodeView    返回类型 
	* @throws
	 */
	public static TreeNodeView getTreeNodeViewById(String id,List<TreeNodeView> list){
		for(TreeNodeView treeNodeView : list){
    		if(id.equals(treeNodeView.getNodeId())){
    			return treeNodeView;
    		}
    	}
		return null;
	}
	
	/**
	 * 
	* @Title: getTreeNodeViewById 
	* @Description: 得到缓存中的节点
	* @param @param id
	* @param @param list
	* @return TreeNodeView    返回类型 
	* @throws
	 */
	public static TreeNodeView getTreeNodeViewByIdFromCache(String id){
		for(TreeNodeView treeNodeView : nodeList){
    		if(id.equals(treeNodeView.getNodeId())){
    			return treeNodeView;
    		}
    	}
		return null;
	}
	
	/**
	 * 
	* @Title: getChildrenTreeNodeListByParentIdFromCache 
	* @Description: 遍历缓存中的父节点的子节点
	* @return void    返回类型 
	* @throws
	 */
	public static List<TreeNodeView> getChildrenTreeNodeListByParentIdFromCache(String parentId){
		List<TreeNodeView> childrenList = new ArrayList<TreeNodeView>();
		for(TreeNodeView treeNode : nodeList){
    		if(parentId.equals(treeNode.getNodeParentId())){
    			childrenList.add(treeNode);
    		}
    	}
		if(childrenList.size() == 0){
			return null;
		}
		return childrenList;
	}
	
	/**
	 * 
	* @Title: getRootTreeNode 
	* @Description: 得到树的根节点(root)
	* @param @return    设定文件 
	* @return TreeNodeView    返回类型 
	* @throws
	 */
	public static TreeNodeView getRootTreeNode(String rootNodeId){
		//refreshNodeList(list);
		//找到树状图的根节点root
		TreeNodeView rootNode = new TreeNodeView();
    	for(TreeNodeView treeNodeView : nodeList){
    		String nodeId = treeNodeView.getNodeId();
    		if(nodeId.equals(rootNodeId)){
    			rootNode = treeNodeView;
    		}
    	}
		return rootNode;
	}
	
	/**
	 * 
	* @Title: initRootChildrenNode 
	* @Description: 初始化root节点的子节点信息
	* @param @param parentNode    设定文件 
	* @return void    返回类型 
	* @throws
	 */
	public static TreeNodeView initRootChildrenNode(TreeNodeView parentNode){
		
		String parentId = parentNode.getNodeId();
		List<TreeNodeView> childrenList = new ArrayList<TreeNodeView>();
		for(TreeNodeView treeNodeView : nodeList){
			if(parentId.equals(treeNodeView.getNodeParentId())){
				initRootChildrenNode(treeNodeView);
				childrenList.add(treeNodeView);
			}
		}
		
		if(childrenList.size() == 0){
			return parentNode;
		}
		TreeNodeView[] children = new TreeNodeView[childrenList.size()];
		for(int i = 0;i<childrenList.size();i++){
			children[i] = childrenList.get(i);
		}
		//parentNode.setChildren(children);// = children;
		parentNode.setChildren(childrenList);
		return parentNode;
	}
	
	public static TreeNodeView initRootChildrenNodeList(TreeNodeView parentNode){
		String parentId = parentNode.getNodeId();
		List<TreeNodeView> childrenList = new ArrayList<TreeNodeView>();
		for(TreeNodeView treeNodeView : nodeList){
			if(parentId.equals(treeNodeView.getNodeParentId())){
				initRootChildrenNode(treeNodeView);
				childrenList.add(treeNodeView);
			}
		}
		
		if(childrenList.size() == 0){
			return parentNode;
		}
		//TreeNodeView[] children = new TreeNodeView[childrenList.size()];
		//for(int i = 0;i<childrenList.size();i++){
			//children[i] = childrenList.get(i);
		//}
		parentNode.setChildren(childrenList);// = children;
		return parentNode;
	}
	
	/**
	 * 
	* @Title: getIsAddCodeList 
	* @Description: 根据树节点得到此节点允许增加的Code码节点
	* @param @param treeNodeView
	* @param @param codeNodeList
	* @param @return    设定文件 
	* @return List<CodeNode>    返回类型 
	* @throws
	 */
	public static List<CodeNode> getIsAddCodeList(TreeNodeView treeNodeView,List<CodeNode> codeNodeList){
		/*
		 * 遍历原则是：
		 * 		1:类型优先级：渠道Channel > 设备device > 页面Page
		 * 		2:再比较级别,例如 C1 > C2 > C3
		 */
		String id = treeNodeView.getCodeId();
		CodeNode codeNode = TreeNodeViewUtil.getCodeNodeById(id, codeNodeList);
		
		String codeType = codeNode.getCodetype();
		
		if("Channel".equals(codeType)){
			
		}
		
		return null;
	}
	
	/**
	 * 
	* @Title: getCodeNodeById 
	* @Description: 根据id查询Code码的信息
	* @param @param id
	* @param @param codeNodeList
	* @param @return    设定文件 
	* @return CodeNode    返回类型 
	* @throws
	 */
	public static CodeNode getCodeNodeById(String id,List<CodeNode> codeNodeList){
		for(CodeNode codeNode : codeNodeList){
    		if(id.equals(codeNode.getId())){
    			return codeNode;
    		}
    	}
		return null;
	}
	
	/**
	 * 
	* @Title: getCodeNodeById 
	* @Description: 根据code查询Code码的信息
	* @param @param id
	* @param @param codeNodeList
	* @param @return    设定文件 
	* @return CodeNode    返回类型 
	* @throws
	 */
	public static CodeNode getCodeNodeByCode(String code,List<CodeNode> codeNodeList){
		for(CodeNode codeNode : codeNodeList){
    		if(code.equals(codeNode.getCode())){
    			return codeNode;
    		}
    	}
		return null;
	}
	
	/**
	 * 
	* @Title: getChildrenTreeNodeListByParentId 
	* @Description: 根据父节点id查询其子节点列表信息
	* @param @param id
	* @param @param codeNodeList
	* @param @return    设定文件 
	* @return CodeNode    返回类型 
	* @throws
	 */
	public static List<TreeNodeView> getChildrenTreeNodeListByParentId(String parentId,List<TreeNodeView> treeNodeList){
		List<TreeNodeView> childrenList = new ArrayList<TreeNodeView>();
		for(TreeNodeView treeNode : treeNodeList){
    		if(parentId.equals(treeNode.getNodeParentId())){
    			childrenList.add(treeNode);
    		}
    	}
		if(childrenList.size() == 0){
			return null;
		}
		return childrenList;
	}
	
	/**
	 * 
	* @Title: initConditionFSConversion 
	* @Description: 初始化转化率表的查询语句
	* @param @param treeNodeView
	* @return StatisticsSqlVO    返回类型 
	* @throws
	 */
	public static StatisticsSqlVO initConditionFSConversion(TreeNodeView treeNodeView,String beginDate,String endDate){
		StatisticsSqlVO ssvo = new StatisticsSqlVO();
		//设置时间的查询范围，前端判断不能为空
		ssvo.setBeginDate(beginDate);
		ssvo.setEndDate(endDate);
		//没有联合查询等复杂设计，from后面只有一张表
		ssvo.setFrom(new String[]{"flow_statistics_conversion"});
		//根据节点类型设置相应的值，共三种渠道设备页面，对应字段page_code，channel_code，platform_code
		String codeType = treeNodeView.getCodeType();
		if(codeType!=null&&(codeType.equals(Channel)||codeType.equals(Device)||codeType.equals(Page))){
			String codeValue = treeNodeView.getCodeValue();
			//下面设置的codeValue应该是code表中子节点的所有值
			CodeNode cn = TreeNodeViewUtil.getCodeNodeByCode(codeValue, codeList);
			List<String> codeValueList = TreeNodeViewUtil.getCodeValueByParent(cn);
			String[] codeValueArr = null;
			if(codeValueList!=null&&codeValueList.size()>0){
				codeValueArr = new String[codeValueList.size()];
				for(int i=0;i<codeValueList.size();i++){
					codeValueArr[i] =  codeValueList.get(i);
				}
			}
			switch(codeType){
				case "Channel":ssvo.setChannleCodeValue(codeValueArr);break;
				case "Device":ssvo.setPlatformCodeValue(codeValueArr);break;
				case "Page":ssvo.setPageCodeValue(codeValueArr);break;
			}
			
			//页面的转化率，按照固定的优先级：详情-订单-支付。之后如果有变动，再另行处理
			if(codeType.equals(Page)){
				switch(codeValue){
					case "3XagQ":ssvo.setParentPageCodeValue(null);break;
					case "3XiaD":ssvo.setParentPageCodeValue(new String[]{"3XagQ"});break;
					case "3ZhiF":ssvo.setParentPageCodeValue(new String[]{"3XiaD"});break;
				}
			}
		}
		
		//分解节点属性集对应的值域
		String attributeSetStr = treeNodeView.getAttributeSet();
		if(attributeSetStr!=null&&attributeSetStr.length()>0){
			String[] attributeSet = attributeSetStr.split(AttrSet_Separator);
			String[] attributeSetValue = attributeSetStr.split(AttrSet_Separator);
			//此处的统计表只有品类一个，可以直接处理。如果有多个再另行处理
			for(int i = 0;i<attributeSet.length;i++){
				if("category".equals(attributeSet[i])){
					ssvo.setCategoryIdValue(new String[]{attributeSetValue[i]});
				}
			}
		}
		
		//判断虚拟值域的设置,处理一些特殊的查询条件
		if("Y".equals(treeNodeView.getVitualNodeFlag())){
			
		}
		//设置select及groupby的值
		List<String> selectList = new ArrayList<String>();selectList.add("sum(amount) sum_amount");
		List<String> groupList = new ArrayList<String>();
		if(ssvo.getCategoryIdValue()!=null){
			selectList.add("category_id");
			groupList.add("category_id");
		}
		if(ssvo.getChannleCodeValue()!=null){
			selectList.add("channel_code");
			groupList.add("channel_code");
		}
		if(ssvo.getPageCodeValue()!=null){
			selectList.add("page_code");
			groupList.add("page_code");
		}
		if(ssvo.getPlatformCodeValue()!=null){
			selectList.add("platform_code");
			groupList.add("platform_code");
		}
		if(ssvo.getParentPageCodeValue()!=null){
			selectList.add("parent_page_code");
			groupList.add("parent_page_code");
		}
		String[] selectValue = new String[selectList.size()];
		for(int i = 0;i<selectList.size();i++){
			selectValue[i] = selectList.get(i);
		}
		ssvo.setSelect(selectValue);
		if(groupList.size()>0){
			String[] groupValue = new String[groupList.size()];
			for(int i = 0;i<groupList.size();i++){
				groupValue[i] = groupList.get(i);
			}
			ssvo.setGroupby(groupValue);
		}
		//测试mybatis
		List ssl = new ArrayList<String>();
		ssl.add("2d44");ssl.add("2d46");ssl.add("2d45");
		ssvo.setSelectAlias(ssl);
		//ssvo.setChannleCodeValue(new String[]{"SELECT sum(rate) sumRate , sum(amount) sumAmount  from flow_statistics_conversion where 1=1 and oper_date='2016-03-16' and channel_code in ( '1232hr','1231t3'  ) group by channel_code"});
		return ssvo;
	}
	
	/**
	 * 
	* @Title: getCodeValueByParent 
	* @Description: 根据父Code码信息，得到属于此父code码的所有codeValue
	* @param @param cn
	* @return String[]    返回类型 
	* @throws
	 */
	public static List<String> getCodeValueByParent(CodeNode cn){
		List<String> list = new ArrayList<String>();
		list.add(cn.getCode());
		for(CodeNode codeNode : codeList){
			if(cn.getId().equals(codeNode.getParentId())){
				List<String> cList = getCodeValueByParent(codeNode);
				if(cList!=null&&cList.size()>0){
					list.addAll(cList);	
				}
			}
			
		}
		if(list.size()==0){
			return null;
		}
		return list;
	}
	
	public static String doubleToString(double dou,String scale,boolean isRate){
		if(isRate){
			BigDecimal bg = new BigDecimal(dou*100);
			double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
			return f1+"%";
		}else{
			Double dd = new Double(dou);
			int i = dd.intValue();
			return i+"";
		}
	}
	
	public static List<TreeNodeView> getParentNodeList(TreeNodeView treeNodeView){
		String parentId = treeNodeView.getNodeParentId();
		if(parentId != null && parentId.length()>0){
			List<TreeNodeView> parentList = new ArrayList<TreeNodeView>();
			for(TreeNodeView tn : nodeList){
				if(parentId.equals(tn.getNodeId())){
					List<TreeNodeView> ll = TreeNodeViewUtil.getParentNodeList(tn);
					parentList.add(tn);
					if(ll!=null&&ll.size()>0){
						parentList.addAll(ll);
					}
				}
			}
			return parentList;
		}
		return null;
	}
	
	/**
	 * 
	* @Title: splitTreeNodeVitualByType 
	* @Description: 得到父节点的虚拟节点
	* @return List<TreeNodeView>    返回类型 
	* @throws
	 */
	public static List<TreeNodeView> splitTreeNodeVitualByType(List<TreeNodeView> treeList,String vitualType){
		List<TreeNodeView> list = new ArrayList<TreeNodeView>();
		for(TreeNodeView tn : treeList){
			if(vitualType.equals(tn.getVitualNodeFlag())){
				list.add(tn);
			}
		}
		return list;
	}
	
	public static List<TreeNodeView> splitTreeNodeByType(List<TreeNodeView> treeList,String codeType){
		List<TreeNodeView> list = new ArrayList<TreeNodeView>();
		for(TreeNodeView tn : treeList){
			if(codeType.equals(tn.getCodeType())){
				list.add(tn);
			}
		}
		return list;
	}
	
	public static TreeNodeView getMaxDepthNodeByList(List<TreeNodeView> treeList){
		TreeNodeView tnv = null;
		int maxDepth = 0;
		for(TreeNodeView tn : treeList){
			if(Integer.parseInt(tn.getNodeDepth()) > maxDepth){
				maxDepth = Integer.parseInt(tn.getNodeDepth());
				tnv = tn;
			}
		}
		return tnv;
	}
	
	public static DeviceStatisticsSqlVO initConditionDeviceFS(TreeNodeView treeNodeView, String beginDate, String endDate){
		DeviceStatisticsSqlVO dssvo = new DeviceStatisticsSqlVO();
		dssvo.setBeginDate(beginDate);
		dssvo.setEndDate(endDate);
		
		
		
		dssvo.setFrom(new String[]{"flow_statistics_nettype"});
		//此表的品类属性只有一个category，另外设备是必查的。
		List<String> category = new ArrayList<String>();
		
		//根据此树节点的信息，需要查询所有其父节点的信息，之后拼接成sql
		String codeType = treeNodeView.getCodeType();
		List<TreeNodeView> parentList = TreeNodeViewUtil.getParentNodeList(treeNodeView);
		//把自己的节点也加入到parent中
		parentList.add(treeNodeView);
		//将父节点列表划分成渠道、设备、页面三个子集，其他的根节点和虚拟节点也划分成子集。相同的渠道设备页面子集取。虚拟节点集同样取最深的节点信息的
		List<TreeNodeView> parentChannelList = TreeNodeViewUtil.splitTreeNodeByType(parentList,Channel);
		List<TreeNodeView> parentDeviceList = TreeNodeViewUtil.splitTreeNodeByType(parentList,Device);
		List<TreeNodeView> parentPageList = TreeNodeViewUtil.splitTreeNodeByType(parentList,Page);
		TreeNodeView tnvChannel = TreeNodeViewUtil.getMaxDepthNodeByList(parentChannelList);
		TreeNodeView tnvDevice = TreeNodeViewUtil.getMaxDepthNodeByList(parentDeviceList);
		TreeNodeView pageDevice = TreeNodeViewUtil.getMaxDepthNodeByList(parentPageList);
		
		if(tnvChannel!=null&&codeType!=Channel){//这两个条件成立，可以设置渠道的信息
			CodeNode cn = TreeNodeViewUtil.getCodeNodeByCode(tnvChannel.getCodeValue(), codeList);
			List<String> codeValueList = TreeNodeViewUtil.getCodeValueByParent(cn);//通过父类得到其子类的所有code值
			String[] codeValueArr = null;
			if(codeValueList!=null&&codeValueList.size()>0){
				codeValueArr = new String[codeValueList.size()];
				for(int i=0;i<codeValueList.size();i++){
					codeValueArr[i] =  codeValueList.get(i);
				}
			}
			switch(codeType){
				case "Channel":dssvo.setChannleCodeValue(codeValueArr);break;
				case "Device":dssvo.setPlatformCodeValue(codeValueArr);break;
				case "Page":dssvo.setPageCodeValue(codeValueArr);break;
			}
			//根据自己的节点属性集，进行拆解，拼接sql
			String attributeSetStr = tnvChannel.getAttributeSet();
			if(attributeSetStr!=null&&attributeSetStr.length()>0){
				String[] attributeSet = attributeSetStr.split(AttrSet_Separator);
				String[] attributeSetValue = attributeSetStr.split(AttrSet_Separator);
				for(int i = 0;i<attributeSet.length;i++){
					if("category".equals(attributeSet[i])){
						category.add(attributeSetValue[i]);
						//dssvo.setCategoryIdValue(new String[]{attributeSetValue[i]});
					}
				}
			}
		}
		
		if(tnvDevice!=null&&codeType!=Device){//这两个条件成立，可以设置设备的信息
			CodeNode cn = TreeNodeViewUtil.getCodeNodeByCode(tnvDevice.getCodeValue(), codeList);
			List<String> codeValueList = TreeNodeViewUtil.getCodeValueByParent(cn);//通过父类得到其子类的所有code值
			String[] codeValueArr = null;
			if(codeValueList!=null&&codeValueList.size()>0){
				codeValueArr = new String[codeValueList.size()];
				for(int i=0;i<codeValueList.size();i++){
					codeValueArr[i] =  codeValueList.get(i);
				}
			}
			switch(codeType){
				case "Channel":dssvo.setChannleCodeValue(codeValueArr);break;
				case "Device":dssvo.setPlatformCodeValue(codeValueArr);break;
				case "Page":dssvo.setPageCodeValue(codeValueArr);break;
			}
			//根据自己的节点属性集，进行拆解，拼接sql
			String attributeSetStr = tnvDevice.getAttributeSet();
			if(attributeSetStr!=null&&attributeSetStr.length()>0){
				String[] attributeSet = attributeSetStr.split(AttrSet_Separator);
				String[] attributeSetValue = attributeSetStr.split(AttrSet_Separator);
				for(int i = 0;i<attributeSet.length;i++){
					if("category".equals(attributeSet[i])){
						category.add(attributeSetValue[i]);
						//dssvo.setCategoryIdValue(new String[]{attributeSetValue[i]});
					}
				}
			}
		}
		
		if(pageDevice!=null&&codeType!=Page){//这两个条件成立，可以设置设备的信息
			CodeNode cn = TreeNodeViewUtil.getCodeNodeByCode(pageDevice.getCodeValue(), codeList);
			List<String> codeValueList = TreeNodeViewUtil.getCodeValueByParent(cn);//通过父类得到其子类的所有code值
			String[] codeValueArr = null;
			if(codeValueList!=null&&codeValueList.size()>0){
				codeValueArr = new String[codeValueList.size()];
				for(int i=0;i<codeValueList.size();i++){
					codeValueArr[i] =  codeValueList.get(i);
				}
			}
			switch(codeType){
				case "Channel":dssvo.setChannleCodeValue(codeValueArr);break;
				case "Device":dssvo.setPlatformCodeValue(codeValueArr);break;
				case "Page":dssvo.setPageCodeValue(codeValueArr);break;
			}
			//根据自己的节点属性集，进行拆解，拼接sql
			String attributeSetStr = pageDevice.getAttributeSet();
			if(attributeSetStr!=null&&attributeSetStr.length()>0){
				String[] attributeSet = attributeSetStr.split(AttrSet_Separator);
				String[] attributeSetValue = attributeSetStr.split(AttrSet_Separator);
				for(int i = 0;i<attributeSet.length;i++){
					if("category".equals(attributeSet[i])){
						category.add(attributeSetValue[i]);
					}
				}
			}
		}
		//根据子集节点的信息设置条件值,加入此节点时虚拟节点，需要特殊处理！！！！！重要！！！！！暂时先不考虑
		//设置品类的查询条件
		if(category.size()>0){
			String[] attr = new String[category.size()];
			for(int i = 0;i<category.size();i++){
				attr[i] = category.get(i);
			}
			dssvo.setCategoryIdValue(attr);
		}
		
		//因为是设备流量统计，groupby的值需要时设备字段即可
		dssvo.setGroupby(new String[]{"platform_code"});
		return dssvo;
	}
	
	public static NettypeStatisticsSqlVO initConditionNettypeFS(TreeNodeView treeNodeView, String beginDate, String endDate){
		NettypeStatisticsSqlVO nssvo = new NettypeStatisticsSqlVO();
		nssvo.setBeginDate(beginDate);
		nssvo.setEndDate(endDate);
		nssvo.setSelect(Arrays.asList("operator_code","sum(Amount) sumAmount"));
		nssvo.setFrom(Arrays.asList("flow_statistics_nettype"));
		nssvo.setGroupby(Arrays.asList("operator_code"));
		nssvo.setOrderby(Arrays.asList("sum_amount"));
		//设置查询条件
		String codeType = treeNodeView.getCodeType();
		List<TreeNodeView> parentList = TreeNodeViewUtil.getParentNodeList(treeNodeView);
		//把自己的节点也加入到parent中
		parentList.add(treeNodeView);
		List<TreeNodeView> parentChannelList = TreeNodeViewUtil.splitTreeNodeByType(parentList,Channel);
		List<TreeNodeView> parentDeviceList = TreeNodeViewUtil.splitTreeNodeByType(parentList,Device);
		List<TreeNodeView> parentPageList = TreeNodeViewUtil.splitTreeNodeByType(parentList,Page);
		TreeNodeView tnvChannel = TreeNodeViewUtil.getMaxDepthNodeByList(parentChannelList);
		TreeNodeView tnvDevice = TreeNodeViewUtil.getMaxDepthNodeByList(parentDeviceList);
		TreeNodeView tnvPage = TreeNodeViewUtil.getMaxDepthNodeByList(parentPageList);
		
		if(tnvChannel!=null){
			CodeNode cn = TreeNodeViewUtil.getCodeNodeByCode(tnvChannel.getCodeValue(), codeList);
			List<String> codeValueList = TreeNodeViewUtil.getCodeValueByParent(cn);//通过父类得到其子类的所有code值
			nssvo.setChannelCode(codeValueList);
		}
		
		if(tnvDevice!=null){
			CodeNode cn = TreeNodeViewUtil.getCodeNodeByCode(tnvDevice.getCodeValue(), codeList);
			List<String> codeValueList = TreeNodeViewUtil.getCodeValueByParent(cn);
			nssvo.setPlatformCode(codeValueList);
		}
		
		if(tnvPage!=null){
			CodeNode cn = TreeNodeViewUtil.getCodeNodeByCode(tnvPage.getCodeValue(), codeList);
			List<String> codeValueList = TreeNodeViewUtil.getCodeValueByParent(cn);
			nssvo.setPageCode(codeValueList);
		}
		//根据品类列表信息，设置条件。过滤parentList，取出所有的属性。目前此表中只有category_id字段，所以只取品类属性
		List<String> categoryList = new ArrayList<String>();//品类的属性集
		categoryList = getParentAttributesAndValue(parentList,"category");
		nssvo.setCategoryId(categoryList);
		
		//根据虚拟节点，增加条件信息。虚拟节点都是最简单的表达，不要设成很复杂。
		List<TreeNodeView> vitualList = TreeNodeViewUtil.splitTreeNodeByType(parentList,"Y");
		if(vitualList!=null&&vitualList.size()>0){
			
		}
		
		return nssvo;
	}
	
	public static RegionStatisticsSqlVO initConditionRegionFS(TreeNodeView treeNodeView, String beginDate, String endDate){
		RegionStatisticsSqlVO rssvo = new RegionStatisticsSqlVO();
		rssvo.setBeginDate(beginDate);
		rssvo.setEndDate(endDate);
		rssvo.setSelect(Arrays.asList("region_code","sum(Amount) sumAmount"));
		rssvo.setFrom(Arrays.asList("flow_statistics_region"));
		rssvo.setGroupby(Arrays.asList("region_code"));
		rssvo.setOrderby(Arrays.asList("sum_amount"));
		
		//设置查询条件
		String codeType = treeNodeView.getCodeType();
		List<TreeNodeView> parentList = TreeNodeViewUtil.getParentNodeList(treeNodeView);
		//把自己的节点也加入到parent中
		parentList.add(treeNodeView);
		List<TreeNodeView> parentChannelList = TreeNodeViewUtil.splitTreeNodeByType(parentList,Channel);
		List<TreeNodeView> parentDeviceList = TreeNodeViewUtil.splitTreeNodeByType(parentList,Device);
		List<TreeNodeView> parentPageList = TreeNodeViewUtil.splitTreeNodeByType(parentList,Page);
		TreeNodeView tnvChannel = TreeNodeViewUtil.getMaxDepthNodeByList(parentChannelList);
		TreeNodeView tnvDevice = TreeNodeViewUtil.getMaxDepthNodeByList(parentDeviceList);
		TreeNodeView tnvPage = TreeNodeViewUtil.getMaxDepthNodeByList(parentPageList);
		
		if(tnvChannel!=null){
			CodeNode cn = TreeNodeViewUtil.getCodeNodeByCode(tnvChannel.getCodeValue(), codeList);
			List<String> codeValueList = TreeNodeViewUtil.getCodeValueByParent(cn);//通过父类得到其子类的所有code值
			rssvo.setChannelCode(codeValueList);
		}
		
		if(tnvDevice!=null){
			CodeNode cn = TreeNodeViewUtil.getCodeNodeByCode(tnvDevice.getCodeValue(), codeList);
			List<String> codeValueList = TreeNodeViewUtil.getCodeValueByParent(cn);
			rssvo.setPlatformCode(codeValueList);
		}
		
		if(tnvPage!=null){
			CodeNode cn = TreeNodeViewUtil.getCodeNodeByCode(tnvPage.getCodeValue(), codeList);
			List<String> codeValueList = TreeNodeViewUtil.getCodeValueByParent(cn);
			rssvo.setPageCode(codeValueList);
		}
		//根据品类列表信息，设置条件。过滤parentList，取出所有的属性。目前此表中只有category_id字段，所以只取品类属性
		List<String> categoryList = new ArrayList<String>();//品类的属性集
		categoryList = getParentAttributesAndValue(parentList,"category");
		rssvo.setCategoryId(categoryList);
		
		//根据虚拟节点，增加条件信息。虚拟节点都是最简单的表达，不要设成很复杂。
		List<TreeNodeView> vitualList = TreeNodeViewUtil.splitTreeNodeByType(parentList,"Y");
		if(vitualList!=null&&vitualList.size()>0){
			
		}
		return rssvo;
	}
	
	/**
	 * 
	* @Title: getParentAttributesAndValue 
	* @Description: 根据父节点的列表，取所有的属性值
	* @return List<String>    返回类型 
	* @throws
	 */
	public static List<String> getParentAttributesAndValue(List<TreeNodeView> parentList,String attrName){
		List<String> valueList = new ArrayList<>();
		Set<String> valueSet = new HashSet<String>();//有重复的去重
		for(TreeNodeView tv : parentList){
			String attributeStr = tv.getAttributeSet();
			if(attributeStr!=null&&attributeStr.length()>0){
				String[] attList = attributeStr.split(AttrSet_Separator);
				for(int i = 0;i<attList.length;i++){
					if(attrName.equals(attList[i])){
						//增加特殊值域对应的子集，例如：门票表示组合门票、景点门票等5->11,12,13
						String[] attrValueList = tv.getAttributeValues().split(AttrSet_Separator);
						String attrValue = attrValueList[i];
						if(attrName.equals("category")&&attrValue.equals("5")){
							valueSet.add("11");
							valueSet.add("12");
							valueSet.add("13");
						}else{
							valueSet.add(attrValue);
						}
					}
				}
			}
		}
		Iterator<String> it = valueSet.iterator();
		while(it.hasNext()){
			String o = it.next();
			valueList.add(o);
	    }
		return valueList;
	}
	
	public static CommonStatisticsSqlVO initConditionCommonFS(TreeNodeView treeNodeView, String beginDate, String endDate, String countType){
		CommonStatisticsSqlVO ssvo = new CommonStatisticsSqlVO();
		List<String> columnList = new ArrayList<String>();
		if("DeviceCount".equals(countType)){
			ssvo.setBeginDate(beginDate);
			ssvo.setEndDate(endDate);
			ssvo.setSelect("platform_code commonCode,sum(Amount) sumAmount");
			ssvo.setFrom("flow_statistics");
			ssvo.setGroupby("platform_code");
			ssvo.setOrderby("sumAmount");
			ssvo.setOrderAsc("desc");
			columnList.addAll(Arrays.asList("channel_code","platform_code","page_code","category_id"));
		}else if("NetTypeCount".equals(countType)){
			ssvo.setBeginDate(beginDate);
			ssvo.setEndDate(endDate);
			ssvo.setSelect("operator_code commonCode,sum(Amount) sumAmount");
			ssvo.setFrom("flow_statistics_nettype");
			ssvo.setGroupby("operator_code");
			ssvo.setOrderby("sumAmount");
			ssvo.setOrderAsc("desc");
			columnList.addAll(Arrays.asList("channel_code","platform_code","page_code","category_id"));
		}else if("RegionCount".equals(countType)){
			ssvo.setBeginDate(beginDate);
			ssvo.setEndDate(endDate);
			ssvo.setSelect("region_code commonCode,sum(Amount) sumAmount");
			ssvo.setFrom("flow_statistics_region");
			ssvo.setGroupby("region_code");
			ssvo.setOrderby("sumAmount");
			ssvo.setOrderAsc("desc");
			columnList.addAll(Arrays.asList("channel_code","platform_code","page_code","category_id"));
		}else if("flow_statistics".equals(countType)){//转化率查询，树节点显示数据及百分比
			ssvo.setBeginDate(beginDate);
			ssvo.setEndDate(endDate);
			ssvo.setSelect("ifnull(sum(Amount),0) sumAmount");
			ssvo.setFrom("flow_statistics");
			columnList.addAll(Arrays.asList("channel_code","platform_code","page_code","category_id"));
		}
		//根据字段列表的值，来拼接sql语句,即设置where的值
		//设置查询条件
		List<TreeNodeView> parentList = TreeNodeViewUtil.getParentNodeList(treeNodeView);
		//把自己的节点也加入到parent中
		parentList.add(treeNodeView);
		
		String whereStr = "";
		for(String str : columnList){
			String strAlias = TreeNodeViewUtil.treeUtilProperties.getProperty("column."+str, str);
			if(strAlias.equals("Channel")||strAlias.equals("Page")||strAlias.equals("Device")){
				List<TreeNodeView> typeList = TreeNodeViewUtil.splitTreeNodeByType(parentList,strAlias);
				TreeNodeView tnv = TreeNodeViewUtil.getMaxDepthNodeByList(typeList);
				if(tnv!=null){
					CodeNode cn = TreeNodeViewUtil.getCodeNodeByCode(tnv.getCodeValue(), codeList);
					List<String> codeValueList = TreeNodeViewUtil.getCodeValueByParent(cn);//通过父类得到其子类的所有code值
					String valueStr = "";
					for(String value : codeValueList){
						valueStr = valueStr + "'"+value+"',";
					}
					if(valueStr.length()>0){
						whereStr = whereStr + " and " + str + " in "+" ( " + valueStr.substring(0, valueStr.length()-1) +" ) ";
					}
				}
			}
			if(strAlias.equals("category")){
				List<String> attrValueList = TreeNodeViewUtil.getParentAttributesAndValue(parentList,strAlias);
				String valueStr = "";
				for(String value : attrValueList){
					valueStr = valueStr + "'"+value+"',";
				}
				if(valueStr.length()>0){
						whereStr = whereStr + " and " + str + " in "+" ( " + valueStr.substring(0, valueStr.length()-1) +" ) ";
				}
			}
		}
		
		//查询转化率的特殊点：需要取父页面的parent_page_code,有则加，没有则不加
		if("ConversionCount".equals(countType)){
			TreeNodeView t = TreeNodeViewUtil.getTreeNodeViewByIdFromCache(treeNodeView.getNodeParentId());
			if("Page".equals(t.getCodeType())){
				String str = t.getCodeValue();
				whereStr = whereStr + " and parent_page_code = '" + str +"'";
			}
		}
		
		//取虚拟节点的信息
		List<TreeNodeView> vitualList = TreeNodeViewUtil.splitTreeNodeVitualByType(parentList, "Y");
		//同一虚拟节点类型的取最深的节点
		List<TreeNodeView> vitualMaxDepthList = TreeNodeViewUtil.getMaxDepthVitualNodeByList(vitualList);
		for(TreeNodeView tv : vitualMaxDepthList){
			List<String> deviceList = new ArrayList<String>();
			if(tv.getNodeId().equals("6")){
				deviceList.addAll(TreeNodeViewUtil.getDeviceValue("ios"));
			}else if(tv.getNodeId().equals("7")){
				deviceList.addAll(TreeNodeViewUtil.getDeviceValue("android"));
			}else if(tv.getNodeId().equals("2")){
				deviceList.addAll(TreeNodeViewUtil.getDeviceValue("ios"));
				deviceList.addAll(TreeNodeViewUtil.getDeviceValue("android"));
			}
			if(deviceList.size()>0){
				String valueStr = "";
				for(String value : deviceList){
					valueStr = valueStr + "'"+value+"',";
				}
				if(valueStr.length()>0){
					whereStr = whereStr + " and platform_code in ( " + valueStr.substring(0, valueStr.length()-1) + " )" ;//+ " and channel_code = '116yq5'";
					//增加自有渠道条件：包括"自有渠道"及以后增加的子节点
					List<String> cnStr = TreeNodeViewUtil.getCodeValueByParent(TreeNodeViewUtil.getCodeNodeByCode("116yq5", codeList));
					if(cnStr!=null&&cnStr.size()>0){
						String ziYouQuDao = "";
						for(String value : cnStr){
							ziYouQuDao = ziYouQuDao + "'"+value+"',";
						}
						if(ziYouQuDao.length()>0){
							whereStr = whereStr + " and channel_code in ( " + ziYouQuDao.substring(0,ziYouQuDao.length()-1) + " )";
						}
					}
				}
			}
		}
		ssvo.setWhere(whereStr);
		return ssvo;
	}
	
	public static List<TreeNodeView> getMaxDepthVitualNodeByList(List<TreeNodeView> treeList){
		List<TreeNodeView> returnList = new ArrayList<TreeNodeView>();
		Set<String> setVitualType = new HashSet<String>();
		//遍历虚拟节点的所有类型
		for(TreeNodeView tnv : treeList){
			setVitualType.add(tnv.getCodeType());
		}
		//按虚拟类型查询深度最大的虚拟节点
		for(String str : setVitualType){
			TreeNodeView tnv = null;
			int maxDepth = 0;
			for(TreeNodeView tn : treeList){
				if(str.equals(tn.getCodeType()) && Integer.parseInt(tn.getNodeDepth()) > maxDepth){
					maxDepth = Integer.parseInt(tn.getNodeDepth());
					tnv = tn;
				}
			}
			if(tnv!=null){
				returnList.add(tnv);
			}
		}
		return returnList;
	}
	
	public static List<String> getDeviceValue(String subSring){
		List<String> valueList = new ArrayList<String>();
		for(CodeNode cn : codeList){
			if(cn.getCodetype()!=null&&cn.getName()!=null)
				if(cn.getCodetype().equals(Device)&&cn.getName().startsWith(subSring)){
					valueList.add(cn.getCode());
				}
		}
		return valueList;
	}
	
	public static Map handleResultListInfo(String countType,String maxShow,List<CommonStatisticsResult> list){
		Map map = new HashMap();
		map.put("maxShow", maxShow);
		//计算列表的总和，及各占百分比
		double total = 0;
		for(CommonStatisticsResult com : list){
			//按照code码表的name映射，否则按照perproties的值域映射
			com.setNamedesc(TreeNodeViewUtil.treeUtilProperties.getProperty(com.getCommonCode(),com.getCommonCode()));
			total = total + com.getSumAmount();
		}
		map.put("total", total);
		
		//每个列表的占比
		for(CommonStatisticsResult com : list){
			BigDecimal bg = new BigDecimal(com.getSumAmount()*100/total);
			double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
			com.setPercentage(f1+"%");
		}
		
		//取前十名的占比
		double totalFenZi = 0;
		for(int i = 0;i<list.size();i++){
			if(i<Integer.valueOf(maxShow)){
				totalFenZi = totalFenZi + list.get(i).getSumAmount();
			}
		}
		
		if(total>0){
			BigDecimal bg2 = new BigDecimal(totalFenZi*100/total);
			double f2 = bg2.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
			map.put("totalPercentage", f2+"%");
		}else{
			map.put("totalPercentage", "0");
		}
		return map;
	}
	
	public static String checkDate(String beginDate,String endDate){
		String mess = "";
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date begin;
		Date end;
		Date now;
		Date before;
		Date cross;
		try {
			begin = sdf.parse(beginDate);
			end = sdf.parse(endDate);
			Date dnow = new Date();
			now = sdf.parse(sdf.format(dnow));
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(dnow);
			calendar.add(calendar.YEAR, -3);//设置为前3年
			Date dBefore = calendar.getTime();//得到前3月的时间
			before = sdf.parse(sdf.format(dBefore));
			
			Calendar calendarc = Calendar.getInstance();
			calendarc.setTime(end);
			calendarc.add(calendarc.MONTH, -6);//设置为前3月
			cross = sdf.parse(sdf.format(calendarc.getTime()));
			
			//先比较结束日期不能大于当前日期
			if(now.compareTo(end)>=0){
				
			}else{
				return "a";
			}
			//比较结束日期不能小于开始日期
			if(end.compareTo(begin)>=0){
				
			}else{
				return "b";
			}
			//开始时间最大是两年前
			if(begin.compareTo(before)>=0){
				
			}else{
				return "c";
			}
			//比较开始和结束日期的跨度
			if(begin.compareTo(cross)>=0){
				
			}else{
				return "d";
			}
		} catch (ParseException e1) {
			e1.printStackTrace();
		}
		return mess;
	}
	
	public static void main(String[] args){
		List<String> valueList = new ArrayList<String>();
		List<String> valueList1 = new ArrayList<String>();
		valueList.addAll(valueList1);
		System.out.println(valueList.size());
		Date dNow = new Date();
		System.out.println(dNow);
		String astr = checkDate("2013-10-27","2013-12-27");
		
		System.out.println(astr);
	}
}
